home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / ntp_src / ntp_prot.c < prev    next >
C/C++ Source or Header  |  1992-04-03  |  53KB  |  2,080 lines

  1. /* $Header: ntp_proto.c,v 1.5 91/06/25 11:06:56 ath Exp $ */
  2.  
  3. /*
  4.  * ntp_proto.c - NTP version 2 protocol machinery
  5.  */
  6.  
  7. #include <stdio.h>
  8.  
  9. #include "global.h"
  10. #include "timer.h"
  11. #include "sockaddr.h"
  12.  
  13. #include "ntp_types.h"
  14. #include "ntp_syslog.h"
  15. #include "ntp_fp.h"
  16. #include "ntp.h"
  17.  
  18. /*
  19.  * System variables are declared here.  See Section 3.2 of
  20.  * the specification.
  21.  */
  22. u_char sys_leap;        /* system leap indicator */
  23. u_char sys_stratum;        /* stratum of system */
  24. s_char sys_precision;        /* local clock precision */
  25. u_fp sys_distance;        /* distance to current sync source */
  26. u_fp sys_dispersion;        /* dispersion of system clock */
  27. u_long sys_refid;        /* reference source for local clock */
  28. l_fp sys_reftime;        /* time we were last updated */
  29. u_long sys_hold;        /* system hold counter */
  30. struct peer *sys_peer;        /* our current peer */
  31. u_fp sys_maxskew;        /* a configuration parameter, def NTP_MAXSKW */
  32.  
  33. /*
  34.  * Non-specified system state variables.
  35.  */
  36. int sys_bclient;        /* we set our time to broadcasts */
  37. u_long sys_bdelay;        /* default delay to use for broadcasting */
  38. int sys_authenticate;        /* authenticate time used for syncing */
  39.  
  40. #ifdef XNTP_AUTHENTICATE
  41. u_long sys_authdelay;        /* ts fraction, time it takes for encrypt() */
  42. #endif /* XNTP_AUTHENTICATE */
  43.  
  44. int sys_select_algorithm;    /* experiment algorithm selection */
  45.  
  46. /*
  47.  * Statistics counters
  48.  */
  49. u_long sys_stattime;        /* time when we started recording */
  50. u_long sys_badstratum;        /* packets with invalid incoming stratum */
  51. u_long sys_oldversionpkt;    /* old version packets received */
  52. u_long sys_newversionpkt;    /* new version packets received */
  53. u_long sys_unknownversion;    /* don't know version packets */
  54. u_long sys_badlength;        /* packets with bad length */
  55. u_long sys_processed;        /* packets processed */
  56. u_long sys_badauth;        /* packets dropped because of authorization */
  57. u_long sys_wanderhold;        /* sys_peer held to prevent wandering */
  58.  
  59.  
  60. /*
  61.  * Imported from ntp_timer.c
  62.  */
  63. /* extern u_long current_time;  Now a macro in ntp.h */
  64.  
  65. /*
  66.  * Imported from ntp_io.c
  67.  */
  68. extern struct interface *any_interface;
  69.  
  70. /*
  71.  * The peer hash table.  Imported from ntp_peer.c
  72.  */
  73. extern struct peer *peer_hash[];
  74.  
  75. /*
  76.  * debug flag
  77.  */
  78. extern int debug;
  79.  
  80.  
  81. /*
  82.  * transmit - Transmit Procedure.  See Section 3.4.1 of the specification.
  83.  */
  84. void
  85. transmit(v)
  86.      void *v;            /* Void * to make ntp timer process happy */
  87. {
  88.     struct pkt xpkt;    /* packet to send */
  89.     register struct peer *peer = (struct peer *)v;
  90.     u_long peer_timer;
  91.     extern void unpeer();
  92.     void clock_select();
  93.     void clock_filter();
  94.     void clear();
  95.     extern void sendpkt();
  96.     extern void get_systime();
  97. #ifdef XNTP_AUTHENTICATE
  98.     extern void auth1crypt();
  99.     extern void auth2crypt();
  100.     extern int authhavekey();
  101. #endif  /* XNTP_AUTHENTICATE */
  102.     extern char *ntoa();
  103.  
  104.     if (peer->hmode != MODE_BCLIENT) {
  105.         u_long xkeyid;
  106.  
  107. #ifdef XNTP_AUTHENTICATE
  108.         /*
  109.          * Figure out which keyid to include in the packet
  110.          */
  111.         if ((peer->flags & FLAG_AUTHENABLE)
  112.             && (peer->flags & (FLAG_CONFIG|FLAG_AUTHENTIC))
  113.             && authhavekey(peer->keyid)) {
  114.             xkeyid = peer->keyid;
  115.         } else
  116. #endif  /* XNTP_AUTHENTICATE */
  117.         {
  118.             xkeyid = 0;
  119.         }
  120.  
  121.         /*
  122.          * Make up a packet to send.
  123.          */
  124.         xpkt.li_vn_mode
  125.             = PKT_LI_VN_MODE(sys_leap, peer->version, peer->hmode);
  126.         xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
  127.         if (peer->reach == 0)
  128.             xpkt.ppoll = NTP_MINPOLL;
  129.         else
  130.             xpkt.ppoll = peer->hpoll;
  131.         xpkt.precision = sys_precision;
  132.         xpkt.distance = HTONS_FP(sys_distance);
  133.         xpkt.dispersion = HTONS_FP(sys_dispersion);
  134.         xpkt.refid = sys_refid;
  135.         HTONL_FP(&sys_reftime, &xpkt.reftime);
  136.         HTONL_FP(&peer->org, &xpkt.org);
  137.         HTONL_FP(&peer->rec, &xpkt.rec);
  138.  
  139.         /*
  140.          * Decide whether to authenticate or not.  If so, call encrypt()
  141.          * to fill in the rest of the frame.  If not, just add in the
  142.          * xmt timestamp and send it quick.
  143.          */
  144. #ifdef XNTP_AUTHENTICATE
  145.         if (peer->flags & FLAG_AUTHENABLE) {
  146.             xpkt.keyid = htonl(xkeyid);
  147.             auth1crypt(xkeyid, (u_long *)&xpkt, LEN_PKT_NOMAC);
  148.             get_systime(&peer->xmt);
  149.             L_ADDUF(&peer->xmt, sys_authdelay);
  150.             HTONL_FP(&peer->xmt, &xpkt.xmt);
  151.             auth2crypt(xkeyid, (u_long *)&xpkt, LEN_PKT_NOMAC);
  152.             sendpkt(&(peer->srcadr), peer->dstadr, &xpkt,
  153.                 LEN_PKT_MAC);
  154. #ifdef DEBUG
  155.             if (debug > 1)
  156.                 printf("transmit auth to %s\n",
  157.                     ntoa(&(peer->srcadr)));
  158. #endif
  159.             peer->sent++;
  160.         } else
  161. #endif  /* XNTP_AUTHENTICATE */
  162.           {
  163.             /*
  164.              * Get xmt timestamp, then send it without mac field
  165.              */
  166.             get_systime(&(peer->xmt));
  167.             HTONL_FP(&peer->xmt, &xpkt.xmt);
  168.             sendpkt(&(peer->srcadr), peer->dstadr, &xpkt,
  169.                 LEN_PKT_NOMAC);
  170. #ifdef DEBUG
  171.             if (debug > 1)
  172.                 printf("transmit to %s\n", ntoa(&(peer->srcadr)));
  173. #endif
  174.             peer->sent++;
  175.         }
  176.     }
  177.  
  178.     if (peer->hmode != MODE_BROADCAST) {
  179.         u_char opeer_reach;
  180.         /*
  181.          * Determine reachability and diddle things if we
  182.          * haven't heard from the host for a while.
  183.          */
  184.         opeer_reach = peer->reach;
  185.         peer->reach <<= 1;
  186.         if (peer->reach == 0) {
  187. #ifdef XNTP_MODE6
  188.             if (opeer_reach != 0)
  189.                 report_event(EVNT_UNREACH, peer);
  190. #endif  /* XNTP_MODE6 */
  191.             /*
  192.              * Clear this guy out.  No need to redo clock
  193.              * selection since by now this guy won't be a player
  194.              */
  195.             if (peer->flags & FLAG_CONFIG) {
  196.                 if (opeer_reach != 0) {
  197.                     clear(peer);
  198.                     peer->timereachable = current_time;
  199.                 }
  200.             } else {
  201.                 unpeer(peer);
  202.                 return;
  203.             }
  204.  
  205.             /*
  206.              * While we have a chance, if our system peer
  207.              * is zero or his stratum is greater than the
  208.              * last known stratum of this guy, make sure
  209.              * peer->hpoll is clamped to the minimum before
  210.              * resetting the timer.
  211.              */
  212.             if (sys_peer == 0
  213.                 || sys_peer->stratum > peer->stratum) {
  214.                 peer->hpoll = NTP_MINPOLL;
  215.                 peer->unreach = 0;
  216.             }
  217.         } else if (peer->valid >= 2) {
  218.             l_fp off;
  219.  
  220.             off.l_ui = off.l_uf = 0;
  221.             clock_filter(peer, &off, 0, 1);
  222.             /*
  223.              * Peer must have gotten worse.  Redo selection.
  224.              * A reasonable optimization is to only rerun the
  225.              * selection algorithm if the peer is currently
  226.              * sys_peer.
  227.              */
  228.             if (peer == sys_peer)
  229.                 clock_select(peer);
  230.         } else {
  231.             peer->valid++;
  232.         }
  233.     }
  234.  
  235.     /*
  236.      * Arrange for our next time out.  hpoll will be less than
  237.      * NTP_MAXPOLL for sure
  238.      */
  239.     peer_timer = 1 << max(min(peer->ppoll, peer->hpoll), NTP_MINPOLL);
  240. /*    peer->event_timer.event_time = current_time + peer_timer;*/
  241.     peer->event_timer.duration = SEC2TICKS(peer_timer);
  242. /*    TIMER_ENQUEUE(timerqueue, &peer->event_timer);*/
  243.     start_timer (&peer->event_timer);
  244.  
  245.     /*
  246.      * Finally, update the host-poll variable.
  247.      */
  248.     if (peer == sys_peer || (peer->flags & FLAG_MINPOLL)
  249.         || peer->hmode == MODE_BROADCAST || peer->hmode == MODE_BCLIENT) {
  250.         /* clamp it */
  251.         peer->hpoll = NTP_MINPOLL;
  252.     } else if (peer->reach == 0) {
  253.         /*
  254.          * If the peer has been unreachable for a while
  255.          * and we have a system peer who is at least his
  256.          * equal, we may want to ramp his polling interval
  257.          * up to avoid the useless traffic.
  258.          */
  259.         if (sys_peer != 0
  260.             && sys_peer->stratum <= peer->stratum) {
  261.             if (peer->unreach < 16) {
  262.                 peer->unreach++;
  263.                 peer->hpoll = NTP_MINPOLL;
  264.             } else if (peer->hpoll < NTP_MAXPOLL) {
  265.                 peer->hpoll++;
  266.                 peer->ppoll = peer->hpoll;
  267.             }
  268.         }
  269.     } else if (peer->estdisp > PEER_THRESHOLD) {
  270.         if (peer->hpoll > NTP_MINPOLL)
  271.             peer->hpoll--;
  272.     } else if (peer->trust == 0 || (peer->trust & 0x1) != 0) {
  273.         /*
  274.          * Don't increase the polling interval if we're
  275.          * clearing out untrustworthy data.
  276.          */
  277.         if (peer->hpoll < NTP_MAXPOLL)
  278.             peer->hpoll++;
  279.     }
  280. }
  281.  
  282.  
  283. /*
  284.  * receive - Receive Procedure.  See section 3.4.2 in the specification.
  285.  */
  286. void
  287. receive(rbufp)
  288.     struct recvbuf *rbufp;
  289. {
  290.     register struct peer *peer;
  291.     register struct pkt *pkt;
  292.     register u_char hismode;
  293.     int restrict;
  294.     int has_mac;
  295.     int trustable;
  296.     int is_authentic;
  297.     u_long hiskeyid;
  298.     void process_packet();
  299.     void fast_xmit();
  300.     void clock_select();
  301.     void clear();
  302.     extern void unpeer();
  303.     extern void monitor();
  304.     extern int restrictions();
  305. #ifdef XNTP_AUTHENTICATE
  306.     extern int authdecrypt();
  307.     extern int authistrusted();
  308. #endif  /* XNTP_AUTHENTICATE */
  309.     extern struct peer *findpeer();
  310.     extern struct peer *newpeer();
  311.     extern char *ntoa();
  312.  
  313. #ifdef DEBUG
  314.     if (debug > 1)
  315.         printf("receive from %s, length %d\n",
  316.                ntoa(&(rbufp->recv_srcadr)), rbufp->recv_length);
  317. #endif
  318.  
  319. #ifdef XNTP_MONITOR
  320.     /*
  321.      * Let the monitoring software take a look at this first.
  322.      */
  323.     monitor(rbufp);
  324. #endif  /* XNTP_MONITOR */
  325.  
  326.     /*
  327.      * Get the restrictions on this guy.  If we're to ignore him,
  328.      * go no further.
  329.      */
  330.     restrict = restrictions(&rbufp->recv_srcadr);
  331.     if (restrict & RES_IGNORE)
  332.         return;
  333.  
  334.     /*
  335.      * Get a pointer to the packet.
  336.      */
  337.     pkt = &rbufp->recv_pkt;
  338.  
  339.     /*
  340.      * Catch packets whose version number we can't deal with
  341.      */
  342.     if (PKT_VERSION(pkt->li_vn_mode) == NTP_VERSION) {
  343.         sys_newversionpkt++;
  344.     } else if (PKT_VERSION(pkt->li_vn_mode) == NTP_OLDVERSION) {
  345.         sys_oldversionpkt++;
  346.     } else {
  347.         sys_unknownversion++;
  348.         return;
  349.     }
  350.  
  351.     /*
  352.      * Catch private mode packets.  Dump it if queries not allowed.
  353.      */
  354.     if (PKT_MODE(pkt->li_vn_mode) == MODE_PRIVATE) {
  355. #ifdef XNTP_MODE7
  356.         if (restrict & RES_NOQUERY)
  357.             return;
  358.         process_private(rbufp, ((restrict&RES_NOMODIFY) == 0));
  359. #endif  /* XNTP_MODE7 */
  360.         return;
  361.     }
  362.  
  363.     /*
  364.      * Same with control mode packets.
  365.      */
  366.     if (PKT_MODE(pkt->li_vn_mode) == MODE_CONTROL) {
  367. #ifdef XNTP_MODE6
  368.         if (restrict & RES_NOQUERY)
  369.             return;
  370.         process_control(rbufp, restrict);
  371. #endif  /* XNTP_MODE6 */
  372.         return;
  373.     }
  374.  
  375.     /*
  376.      * See if we're allowed to serve this guy time.  If not, ignore
  377.      * him.
  378.      */
  379.     if (restrict & RES_DONTSERVE)
  380.         return;
  381.  
  382.     /*
  383.      * Dump anything with a putrid stratum.  These will most likely
  384.      * come from someone trying to poll us with ntpdc.
  385.      */
  386.     if (pkt->stratum > NTP_INFIN) {
  387.         sys_badstratum++;
  388.         return;
  389.     }
  390.  
  391.     /*
  392.      * Find the peer.  This will return a null if this guy
  393.      * isn't in the database.
  394.      */
  395.     peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr);
  396.  
  397.     /*
  398.      * Check the length for validity, drop the packet if it is
  399.      * not as expected.
  400.      *
  401.      * If this is a client mode poll, go no further.  Send back
  402.      * his time and drop it.
  403.      *
  404.      * The scheme we use for authentication is this.  If we are
  405.      * running in non-authenticated mode, we accept both frames
  406.      * which are authenticated and frames which aren't, but don't
  407.      * authenticate.  We do record whether the frame had a mac field
  408.      * or not so we know what to do on output.
  409.      *
  410.      * If we are running in authenticated mode, we only trust frames
  411.      * which have authentication attached, which are validated and
  412.      * which are using one of our trusted keys.  We respond to all
  413.      * other pollers without saving any state.  If a host we are
  414.      * passively peering with changes his key from a trusted one to
  415.      * an untrusted one, we immediately unpeer with him, reselect
  416.      * the clock and treat him as an unmemorable client (this is
  417.      * a small denial-of-service hole I'll have to think about).
  418.      * If a similar event occurs with a configured peer we drop the
  419.      * frame and hope he'll revert to our key again.  If we get a
  420.      * frame which can't be authenticated with the given key, we
  421.      * drop it.  Either we disagree on the keys or someone is trying
  422.      * some funny stuff.
  423.      */
  424. #ifdef XNTP_AUTHENTICATE
  425.     if (rbufp->recv_length == LEN_PKT_MAC) {
  426.         has_mac = 1;
  427.         hiskeyid = ntohl(pkt->keyid);
  428.     } else
  429. #endif  /* XNTP_AUTHENTICATE */
  430.       if (rbufp->recv_length == LEN_PKT_NOMAC) {
  431.         hiskeyid = 0;
  432.         has_mac = 0;
  433.     } else {
  434. #ifdef DEBUG
  435.         if (debug > 2)
  436.             printf("receive: bad length %d\n", rbufp->recv_length);
  437. #endif
  438.         sys_badlength++;
  439.         return;
  440.     }
  441.  
  442.  
  443.  
  444.     /*
  445.      * Figure out his mode and validate it.
  446.      */
  447.     hismode = PKT_MODE(pkt->li_vn_mode);
  448. #ifdef DEBUG
  449.     if (debug > 2)
  450.         printf("receive: his mode %d\n", hismode);
  451. #endif
  452.     if (PKT_VERSION(pkt->li_vn_mode) == NTP_OLDVERSION && hismode == 0) {
  453.         /*
  454.          * Easy.  If it is from the NTP port it is
  455.          * a sym act, else client.
  456.          */
  457.         if (SRCPORT(&rbufp->recv_srcadr) == NTP_PORT)
  458.             hismode = MODE_ACTIVE;
  459.         else
  460.             hismode = MODE_CLIENT;
  461.     } else {
  462.         if (hismode != MODE_ACTIVE && hismode != MODE_PASSIVE &&
  463.             hismode != MODE_SERVER && hismode != MODE_CLIENT &&
  464.             hismode != MODE_BROADCAST) {
  465.             syslog(LOG_ERR, "bad mode %d received from %s",
  466.                 PKT_MODE(pkt->li_vn_mode),
  467.                 ntoa(&rbufp->recv_srcadr));
  468.             return;
  469.         }
  470.     }
  471.  
  472.  
  473.     /*
  474.      * If he included a mac field, decrypt it to see if it is authentic.
  475.      */
  476.     is_authentic = 0;
  477. #ifdef XNTP_AUTHENTICATE
  478.     if (has_mac) {
  479.         if (authhavekey(hiskeyid)) {
  480.             if (authdecrypt(hiskeyid, (u_long *)pkt, LEN_PKT_NOMAC))
  481.                 is_authentic = 1;
  482.             else
  483.                 sys_badauth++;
  484.         }
  485.     }
  486. #endif  /* XNTP_AUTHENTICATE */
  487.  
  488.     /*
  489.      * Dispatch client mode packets which made it this far.
  490.      */
  491.     if (hismode == MODE_CLIENT) {
  492.         fast_xmit(rbufp, hismode, is_authentic);
  493.         return;
  494.     }
  495.  
  496.     /*
  497.      * If this is someone we don't remember from a previous association,
  498.      * dispatch him now.  Either we send something back quick, we
  499.      * ignore him, or we allocate some memory for him and let
  500.      * him continue.
  501.      */
  502.     if (peer == 0) {
  503.         int mymode;
  504.  
  505.         switch(hismode) {
  506.         case MODE_ACTIVE:
  507.             /*
  508.              * See if this guy qualifies as being the least
  509.              * bit memorable.  If so we keep him around for
  510.              * later.  If not, send his time quick.
  511.              */
  512.             if ((restrict & RES_NOPEER)
  513.                 || PKT_LEAP(pkt->li_vn_mode) == LEAP_NOTINSYNC
  514.                 || PKT_TO_STRATUM(pkt->stratum) >= NTP_INFIN
  515.                 || PKT_TO_STRATUM(pkt->stratum) > sys_stratum) {
  516.                 fast_xmit(rbufp, hismode, is_authentic);
  517.                 return;
  518.             }
  519.             mymode = MODE_PASSIVE;
  520.             break;
  521.  
  522.         case MODE_PASSIVE:
  523.         case MODE_SERVER:
  524.             /*
  525.              * These are obvious errors.  Ignore.
  526.              */
  527.             return;
  528.  
  529.         case MODE_BROADCAST:
  530.             /*
  531.              * Sort of a repeat of the above...
  532.              */
  533.             if ((restrict & RES_NOPEER) || !sys_bclient
  534.                 || PKT_LEAP(pkt->li_vn_mode) == LEAP_NOTINSYNC
  535.                 || PKT_TO_STRATUM(pkt->stratum) >= NTP_INFIN
  536.                 || PKT_TO_STRATUM(pkt->stratum) > sys_stratum)
  537.                 return;
  538.             mymode = MODE_BCLIENT;
  539.             break;
  540.         }
  541.  
  542.         /*
  543.          * Okay, we're going to keep him around.  Allocate him
  544.          * some memory.
  545.          */
  546.         peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, mymode,
  547.             (int)PKT_VERSION(pkt->li_vn_mode), hiskeyid);
  548.         if (peer == 0) {
  549.             /*
  550.              * The only way this can happen is if the
  551.              * source address looks like a reference
  552.              * clock.  Since this is an illegal address
  553.              * this is one of those "can't happen" things.
  554.              */
  555.             syslog(LOG_ERR,
  556.                 "receive() failed to peer with %s, mode %d",
  557.                 ntoa(&rbufp->recv_srcadr), mymode);
  558.             return;
  559.         }
  560.     }
  561.  
  562.     /*
  563.      * Mark the time of reception
  564.      */
  565.     peer->timereceived = current_time;
  566.  
  567.     /*
  568.      * If the peer isn't configured, set his keyid and authenable
  569.      * status based on the packet.
  570.      */
  571.     if (!(peer->flags & FLAG_CONFIG)) {
  572. #ifdef XNTP_AUTHENTICATE
  573.         if (has_mac) {
  574.             peer->keyid = hiskeyid;
  575.             peer->flags |= FLAG_AUTHENABLE;
  576.         } else
  577. #endif  /* XNTP_AUTHENTICATE */
  578.           {
  579.             peer->keyid = 0;
  580.             peer->flags &= ~FLAG_AUTHENABLE;
  581.           }
  582.     }
  583.  
  584.  
  585. #ifdef XNTP_AUTHENTICATE
  586.     /*
  587.      * If this message was authenticated properly, note this
  588.      * in the flags.
  589.      */
  590.     if (is_authentic) {
  591.         peer->flags |= FLAG_AUTHENTIC;
  592.     } else {
  593.         /*
  594.          * If this guy is authenable, and has been authenticated
  595.          * in the past, but just failed the authentic test, report
  596.          * the event.
  597.          */
  598. #ifdef XNTP_MODE6
  599.         if (peer->flags & FLAG_AUTHENABLE
  600.             && peer->flags & FLAG_AUTHENTIC)
  601.             report_event(EVNT_PEERAUTH, peer);
  602. #endif  /* XNTP_MODE6 */
  603.         peer->flags &= ~FLAG_AUTHENTIC;
  604.     }
  605. #endif  /* XNTP_AUTHENTICATE */
  606.  
  607.     /*
  608.      * Determine if this guy is basically trustable.
  609.      */
  610.     if (restrict & RES_DONTTRUST)
  611.         trustable = 0;
  612.     else
  613.         trustable = 1;
  614.     
  615. #ifdef XNTP_AUTHENTICATE
  616.     if (sys_authenticate && trustable) {
  617.         if (!(peer->flags & FLAG_CONFIG)
  618.             || (peer->flags & FLAG_AUTHENABLE))
  619.             trustable = 0;
  620.  
  621.         if (has_mac) {
  622.             if (authistrusted(hiskeyid)) {
  623.                 if (is_authentic) {
  624.                     trustable = 1;
  625.                 } else {
  626.                     trustable = 0;
  627.                     peer->badauth++;
  628.                 }
  629.             }
  630.         }
  631.     }
  632. #endif  /* XNTP_AUTHENTICATE */
  633.  
  634.     /*
  635.      * Dispose of the packet based on our respective modes.  We
  636.      * don't drive this with a table, though we probably could.
  637.      */
  638.     switch (peer->hmode) {
  639.     case MODE_ACTIVE:
  640.     case MODE_CLIENT:
  641.         /*
  642.          * Active mode associations are configured.  If the data
  643.          * isn't trustable, ignore it and hope this guy brightens
  644.          * up.  Else accept any data we get and process it.
  645.          */
  646.         switch (hismode) {
  647.         case MODE_ACTIVE:
  648.         case MODE_PASSIVE:
  649.         case MODE_SERVER:
  650.             process_packet(peer, pkt, &(rbufp->recv_time),
  651.                 has_mac, trustable);
  652.             break;
  653.  
  654.         case MODE_BROADCAST:
  655.             /*
  656.              * No good for us, we want real time.
  657.              */
  658.             break;
  659.         }
  660.         break;
  661.  
  662.     case MODE_PASSIVE:
  663.         /*
  664.          * Passive mode associations are (in the current
  665.          * implementation) always dynamic.  If we've risen
  666.          * beyond his stratum, break the connection.  I hate
  667.          * doing this since it seems like a waste.  Oh, well.
  668.          */
  669.         switch (hismode) {
  670.         case MODE_ACTIVE:
  671.             if (PKT_LEAP(pkt->li_vn_mode) == LEAP_NOTINSYNC
  672.                 || PKT_TO_STRATUM(pkt->stratum) >= NTP_INFIN
  673.                 || PKT_TO_STRATUM(pkt->stratum) > sys_stratum) {
  674.                 unpeer(peer);
  675.                 clock_select((struct peer *)0);
  676.                 fast_xmit(rbufp, hismode, is_authentic);
  677.             } else {
  678.                 process_packet(peer, pkt, &(rbufp->recv_time),
  679.                     has_mac, trustable);
  680.             }
  681.             break;
  682.  
  683.         case MODE_PASSIVE:
  684.         case MODE_SERVER:
  685.         case MODE_BROADCAST:
  686.             /*
  687.              * These are errors.  Just ignore the packet.
  688.              * If he doesn't straighten himself out this
  689.              * association will eventually be disolved.
  690.              */
  691.             break;
  692.         }
  693.         break;
  694.  
  695.     
  696.     case MODE_BCLIENT:
  697.         /*
  698.          * Broadcast client pseudo-mode.  We accept both server
  699.          * and broadcast data.  Passive mode data is an error.
  700.          */
  701.         switch (hismode) {
  702.         case MODE_ACTIVE:
  703.             if (PKT_LEAP(pkt->li_vn_mode) == LEAP_NOTINSYNC
  704.                 || PKT_TO_STRATUM(pkt->stratum) >= NTP_INFIN
  705.                 || PKT_TO_STRATUM(pkt->stratum) > sys_stratum) {
  706.                 /*
  707.                  * Strange situation.  We've been receiving
  708.                  * broadcasts from him which we liked, but
  709.                  * we don't like his active mode stuff.  Send
  710.                  * him some time quickly, we'll figure it
  711.                  * out later.
  712.                  */
  713.                 fast_xmit(rbufp, hismode, is_authentic);
  714.             } else {
  715.                 /*
  716.                  * This guy wants to give us real time
  717.                  * when we've been existing on lousy
  718.                  * broadcasts!  Check to make sure data
  719.                  * is authentic.  If so, convert this to
  720.                  * passive mode, clear it out and do it
  721.                  * that way.
  722.                  */
  723.                 peer->hmode = MODE_PASSIVE;
  724.                 clear(peer);
  725.                 process_packet(peer, pkt, &rbufp->recv_time,
  726.                     has_mac, trustable);
  727.             }
  728.             break;
  729.         
  730.         case MODE_PASSIVE:
  731.             break;
  732.         
  733.         case MODE_SERVER:
  734.         case MODE_BROADCAST:
  735.             if (PKT_LEAP(pkt->li_vn_mode) == LEAP_NOTINSYNC
  736.                 || PKT_TO_STRATUM(pkt->stratum) >= NTP_INFIN
  737.                 || PKT_TO_STRATUM(pkt->stratum) > sys_stratum) {
  738.                 /*
  739.                  * Do nothing, he sucks.  Let him time out.
  740.                  */
  741.             } else {
  742.                 process_packet(peer, pkt, &rbufp->recv_time,
  743.                     has_mac, trustable);
  744.             }
  745.             break;
  746.         }
  747.     }
  748. }
  749.  
  750.  
  751. /*
  752.  * process_packet - Packet Procedure, a la Section 3.4.3 of the specification.
  753.  *              Or almost, at least.  If we're in here we have a reasonable
  754.  *            expectation that we will be having a long term relationship
  755.  *            with this host.
  756.  */
  757. void
  758. process_packet(peer, pkt, recv_ts, has_mac, trustable)
  759.     register struct peer *peer;
  760.     register struct pkt *pkt;
  761.     l_fp *recv_ts;
  762.     int has_mac;
  763.     int trustable;
  764. {
  765.     u_long t23_ui, t23_uf;
  766.     u_long t10_ui, t10_uf;
  767.     s_fp di;
  768.     l_fp ci, temp;
  769.     int bogus_pkt = 0;
  770.     int randomize;
  771.     u_char ostratum, oreach;
  772.     void clock_update();
  773.     void poll_update();
  774.     void clock_filter();
  775.     extern char *ntoa();
  776.     extern char *fptoa();
  777.     extern char *umfptoa();
  778.     extern char *mfptoa();
  779.     extern char *lfptoa();
  780.  
  781.     sys_processed++;
  782.     peer->processed++;
  783.  
  784.     /*
  785.      * If the xmt time stamp is the same as the last one from this guy,
  786.      * mark this as bogus.  If the org time stamp isn't the same as the
  787.      * one we sent, mark the packet as bogus and randomize our next
  788.      * time interval to break synchronization.  Randomize if this
  789.      * guy hasn't heard from us for a while.
  790.      */
  791.     
  792.     bogus_pkt = 0;
  793.     randomize = POLL_RANDOMCHANGE;
  794.     NTOHL_FP(&pkt->xmt, &temp);
  795.     if (L_ISHIS(&peer->org, &temp)) {
  796.         peer->oldpkt++;
  797. #ifdef DEBUG
  798.         if (debug)
  799.             printf("peer %s sent an old packet\n",
  800.                 ntoa(&peer->srcadr));
  801. #endif
  802.         if (!L_ISEQU(&peer->org, &temp)
  803.             && (temp.l_ui != 0 || temp.l_uf != 0))
  804.             /* could be attack? */
  805.             return;
  806.         bogus_pkt = 1;
  807.     } else if (PKT_MODE(pkt->li_vn_mode) != MODE_BROADCAST) {
  808.         l_fp temp2;
  809.  
  810.         NTOHL_FP(&(pkt->org), &temp2);
  811.         if (peer->xmt.l_ui == 0 || !L_ISEQU(&temp2, &(peer->xmt))) {
  812.             bogus_pkt = 1;
  813.             randomize = POLL_MAKERANDOM;
  814.             peer->bogusorg++;
  815. #ifdef DEBUG
  816.             if (debug)
  817.                 printf("peer %s includes ts we didn't send\n",
  818.                     ntoa(&peer->srcadr));
  819. #endif
  820.         }
  821.     }
  822.  
  823.  
  824.     /*
  825.      * Now update our state.
  826.      */
  827.     peer->leap = PKT_LEAP(pkt->li_vn_mode);
  828.     peer->pmode = PKT_MODE(pkt->li_vn_mode);
  829. #ifdef XNTP_AUTHENTICATE
  830.     if (has_mac)
  831.         peer->pkeyid = ntohl(pkt->keyid);
  832.     else
  833. #endif  /* XNTP_AUTHENTICATE */
  834.         peer->pkeyid = 0;
  835.     ostratum = peer->stratum;
  836.     peer->stratum = PKT_TO_STRATUM(pkt->stratum);
  837.     peer->ppoll = pkt->ppoll;
  838.     peer->precision = pkt->precision;
  839.     peer->distance = NTOHS_FP(pkt->distance);
  840.     peer->dispersion = NTOHS_FP(pkt->dispersion);
  841.     peer->refid = pkt->refid;
  842.     NTOHL_FP(&pkt->reftime, &peer->reftime);
  843.     peer->org = temp;    /* reuse byte-swapped pkt->xmt */
  844.     peer->rec = *recv_ts;
  845.     oreach = peer->reach;
  846.     if (peer->reach == 0) {
  847.         peer->timereachable = current_time;
  848.         /*
  849.          * If this guy was previously unreachable, set his
  850.          * polling interval to the minimum and reset the
  851.          * unreach counter.
  852.          */
  853.         peer->unreach = 0;
  854.         peer->hpoll = NTP_MINPOLL;
  855.     }
  856.     if (trustable && peer->trust != 0) {
  857.         /*
  858.          * A wart.  If we're getting trustable data
  859.          * but we previously didn't trust him, drop
  860.          * his polling interval to the minimum to try
  861.          * to clear out the filters.
  862.          */
  863.         peer->hpoll = NTP_MINPOLL;
  864.     }
  865.     peer->reach |= 1;
  866.  
  867.  
  868.     /*
  869.      * Call poll_update().  This will either start us, if the
  870.      * association is new, or drop the polling interval if the
  871.      * association is existing and peer->ppoll has been reduced.
  872.      */
  873.     poll_update(peer, peer->hpoll, randomize);
  874.  
  875.     /*
  876.      * If the packet was bogus, exit
  877.      */
  878.     if (bogus_pkt) {
  879.         /*
  880.          * If there was a reachability change report it even
  881.          * though the packet was bogus.
  882.          */
  883. #ifdef XNTP_MODE6
  884.         if (oreach == 0)
  885.             report_event(EVNT_REACH, peer);
  886. #endif  /* XNTP_MODE6 */
  887.         return;
  888.     }
  889.  
  890.     /*
  891.      * Test to see if the peer is synchronized.  If not we mark
  892.      * the data untrustable.
  893.      */
  894.     if (peer->leap == LEAP_NOTINSYNC)
  895.         trustable = 0;
  896.     if ((peer->org.l_ui - peer->reftime.l_ui)
  897.         >= NTP_MAXAGE) {
  898.         peer->seltooold++;
  899.         trustable = 0;
  900.     }
  901.  
  902.     /*
  903.      * If running in a normal polled association, calculate the round
  904.      * trip delay (di) and the clock offset (ci).  We use the equations
  905.      * (reordered from those in the spec):
  906.      *
  907.      * d = (t2 - t3) - (t1 - t0)
  908.      * c = ((t2 - t3) + (t1 - t0)) / 2
  909.      *
  910.      * If running as a broadcast client, these change.  di becomes
  911.      * equal to two times our broadcast delay, while the offset
  912.      * becomes equal to:
  913.      *
  914.      * c = (t1 - t0) + estbdelay
  915.      */
  916.     t10_ui = peer->org.l_ui;    /* peer->org == t1 */
  917.     t10_uf = peer->org.l_uf;
  918.     M_SUB(t10_ui, t10_uf, peer->rec.l_ui, peer->rec.l_uf); /*peer->rec==t0*/
  919.  
  920.     if (PKT_MODE(pkt->li_vn_mode) != MODE_BROADCAST) {
  921.         t23_ui = ntohl(pkt->rec.l_ui);    /* pkt->rec == t2 */
  922.         t23_uf = ntohl(pkt->rec.l_uf);
  923.         M_SUB(t23_ui, t23_uf, ntohl(pkt->org.l_ui),
  924.             ntohl(pkt->org.l_uf));    /* pkt->org == t3 */
  925.     }
  926.  
  927.     /* now have (t2 - t3) and (t0 - t1).  Calculate (ci) and (di) */
  928.     ci.l_ui = t10_ui;
  929.     ci.l_uf = t10_uf;
  930.     if (peer->hmode == MODE_BCLIENT) {
  931. #ifdef notdef
  932.         if (PKT_MODE(pkt->li_vn_mode) == MODE_CLIENT) {
  933.             /*
  934.              * A client mode packet, used for delay computation.
  935.              * Give the data to the filter.
  936.              */
  937.             bdelay_filter(peer, t23_ui, t23_uf, t10_ui, t10_uf);
  938.         }
  939. #endif
  940.         M_ADDUF(ci.l_ui, ci.l_uf, peer->estbdelay>>1);
  941.         di = MFPTOFP(0, peer->estbdelay);
  942.     } else {
  943.         M_ADD(ci.l_ui, ci.l_uf, t23_ui, t23_uf);
  944.         M_RSHIFT(ci.l_i, ci.l_uf);
  945.  
  946.         /*
  947.          * Calculate di in t23 in full precision, then truncate
  948.          * to an s_fp.
  949.          */
  950.         M_SUB(t23_ui, t23_uf, t10_ui, t10_uf);
  951.         di = MFPTOFP(t23_ui, t23_uf);
  952.     }
  953. #ifdef DEBUG
  954.     if (debug > 3)
  955.         printf("offset: %s, delay %s\n", lfptoa(&ci, 9), fptoa(di, 4));
  956. #endif
  957.  
  958.     di += (FP_SECOND >> (-(int)sys_precision))
  959.         + (FP_SECOND >> (-(int)peer->precision)) + sys_maxskew;
  960.  
  961.     if (di <= 0) {        /* value still too raunchy to use? */
  962.         peer->baddelay++;
  963.         return;
  964.     }
  965.     di = max(di, NTP_MINDIST);
  966.  
  967.     /*
  968.      * This one is valid.  Mark it so, give it to clock_filter(),
  969.      */
  970.     peer->valid = 0;
  971.     clock_filter(peer, &ci, (u_fp)di, trustable);
  972.  
  973.     /*
  974.      * If this guy was previously unreachable, report him
  975.      * reachable.  Else if this guy's stratum has changed, report that.
  976.      * Note we do this here so that the peer values we return are
  977.      * the updated ones.
  978.      */
  979. #ifdef XNTP_MODE6
  980.     if (oreach == 0)
  981.         report_event(EVNT_REACH, peer);
  982.     else if (peer->stratum != ostratum)
  983.         report_event(EVNT_PEERSTRAT, peer);
  984. #endif  /* XNTP_MODE6 */
  985.  
  986.     /*
  987.      * Now update the clock.
  988.      */
  989.     clock_update(peer);
  990. }
  991.  
  992.  
  993. /*
  994.  * clock_update - Clock-update procedure, see section 3.4.5.
  995.  */
  996. void
  997. clock_update(peer)
  998.     struct peer *peer;
  999. {
  1000.     u_char oleap;
  1001.     u_char ostratum;
  1002.     void poll_update();
  1003.     void clock_select();
  1004.     void clear_all();
  1005.     extern int local_clock();
  1006.     extern void leap_process();
  1007.     extern char *ntoa();
  1008.  
  1009. #ifdef DEBUG
  1010.     if (debug)
  1011.         printf("clock_update(%s)\n", ntoa(&peer->srcadr));
  1012. #endif
  1013.     /*
  1014.      * If we're holding don't bother with any of this
  1015.      */
  1016.     if (sys_hold > current_time)
  1017.         return;
  1018.  
  1019.     /*
  1020.      * Call the clock selection algorithm to see
  1021.      * if this update causes the peer to change.
  1022.      */
  1023.     clock_select(peer);
  1024.  
  1025.     /*
  1026.      * If this is the current sys_peer update the system state
  1027.      * and the local clock.
  1028.      */
  1029.     if (peer == sys_peer) {
  1030.         oleap = sys_leap;
  1031.         ostratum = sys_stratum;
  1032.         sys_leap = peer->leap;
  1033.         /*
  1034.          * N.B. peer->stratum was guaranteed to be less than
  1035.          * NTP_INFIN by the receive procedure.
  1036.          */
  1037.         sys_stratum = peer->stratum + 1;
  1038.         sys_distance = peer->distance + peer->estdelay;
  1039.         sys_dispersion = peer->dispersion + peer->estdisp;
  1040.         /*
  1041.          * Hack for reference clocks.  Sigh.  This is the
  1042.          * only real silly part, though, so the analogy isn't
  1043.          * bad.
  1044.          */
  1045.         if (peer->flags & FLAG_REFCLOCK
  1046.             && peer->stratum == STRATUM_REFCLOCK)
  1047.             sys_refid = peer->refid;
  1048.         else
  1049.             sys_refid = peer->srcadr.sin_addr.s_addr;
  1050.         sys_reftime = peer->rec;
  1051.  
  1052.         /*
  1053.          * Report changes.  Note that we never sync to
  1054.          * an unsynchronized host.
  1055.          */
  1056. #ifdef XNTP_MODE6
  1057.         if (oleap == LEAP_NOTINSYNC)
  1058.             report_event(EVNT_SYNCCHG, (struct peer *)0);
  1059.         else if (ostratum != sys_stratum)
  1060.             report_event(EVNT_PEERSTCHG, (struct peer *)0);
  1061. #endif  /* XNTP_MODE6 */
  1062.  
  1063.         switch (local_clock(&(peer->estoffset), &(peer->srcadr))) {
  1064.         case -1:
  1065.             /*
  1066.              * Clock is too screwed up.  Just exit for now.
  1067.              */
  1068. #ifdef XNTP_MODE6
  1069.             report_event(EVNT_SYSFAULT, (struct peer *)0);
  1070. #endif  /* XNTP_MODE6 */
  1071.             /*exit(1);*/
  1072.             /* NOS can't exit here.  Log an error and exit */
  1073.             syslog (LOG_ERR, "clock too screwed up\n");
  1074.             break;
  1075.  
  1076.         case 0:
  1077.             /*
  1078.              * Clock was slewed.  Continue on normally.
  1079.              */
  1080.             break;
  1081.  
  1082.         case 1:
  1083.             /*
  1084.              * Clock was stepped.  Clear filter registers
  1085.              * of all peers, and set the system hold.
  1086.              */
  1087.             clear_all();
  1088.             sys_hold = (PEER_SHIFT * (1<<NTP_MINPOLL))
  1089.                 + current_time;
  1090.             leap_process();        /* reset the leap interrupt */
  1091. #ifdef XNTP_MODE6
  1092.             report_event(EVNT_CLOCKRESET, (struct peer *)0);
  1093. #endif  /* XNTP_MODE6 */
  1094.             break;
  1095.         }
  1096.     }
  1097. }
  1098.  
  1099.  
  1100.  
  1101. /*
  1102.  * poll_update - update peer poll interval.  See Section 3.4.8 of the spec.
  1103.  */
  1104. void
  1105. poll_update(peer, new_hpoll, randomize)
  1106.     struct peer *peer;
  1107.     int new_hpoll;
  1108.     int randomize;
  1109. {
  1110.     register struct timer *evp;
  1111.     register u_long new_timer;
  1112.     register int newpoll;
  1113.     u_long ranp2();
  1114.     char *ntoa();
  1115.  
  1116. #ifdef DEBUG
  1117.     if (debug)
  1118.         printf("poll_update(%s, %d, %d)\n", ntoa(&peer->srcadr),
  1119.             new_hpoll, randomize);
  1120. #endif
  1121.     /*
  1122.      * Catch reference clocks here.  The polling interval for a
  1123.      * reference clock is fixed and needn't be maintained by us.
  1124.      */
  1125.     if (peer->flags & FLAG_REFCLOCK)
  1126.         return;
  1127.  
  1128.     /*
  1129.      * This routine * will randomly perturb the new peer.timer if
  1130.      * requested, to try to prevent synchronization with the remote
  1131.      * peer from occuring.  There are three options, based on the
  1132.      * value of randomize:
  1133.      *
  1134.      * POLL_NOTRANDOM - essentially the spec algorithm.  If
  1135.      * peer.timer is greater than the new polling interval,
  1136.      * drop it to the new interval.
  1137.      *
  1138.      * POLL_RANDOMCHANGE - make changes randomly.  If peer.timer
  1139.      * must be changed, based on the comparison about, randomly
  1140.      * perturb the new value of peer.timer.
  1141.      *
  1142.      * POLL_MAKERANDOM - make next interval random.  Calculate
  1143.      * a randomly perturbed poll interval.  If this value is
  1144.      * less that peer.timer, update peer.timer.
  1145.      */
  1146.     if (peer == sys_peer)
  1147.         peer->hpoll = NTP_MINPOLL;
  1148.     else {
  1149.         if (new_hpoll >= NTP_MAXPOLL)
  1150.             peer->hpoll = NTP_MAXPOLL;
  1151.         else if (new_hpoll <= NTP_MINPOLL)
  1152.             peer->hpoll = NTP_MINPOLL;
  1153.         else
  1154.             peer->hpoll = (u_char)new_hpoll;
  1155.     }
  1156.  
  1157.     /* hpoll <= NTP_MAXPOLL for sure */
  1158.     newpoll = (int)max(min(peer->ppoll, peer->hpoll), NTP_MINPOLL);
  1159.     if (randomize == POLL_MAKERANDOM)
  1160.         new_timer = RANDOM_POLL(newpoll, ranp2(RANDOM_SPREAD(newpoll)))
  1161.             /* + current_time*/;
  1162.     else
  1163.         new_timer = (1<<newpoll) /*+ current_time*/;
  1164.     evp = &(peer->event_timer);
  1165.     /* If the timer is not running, or its duration is > the new one,
  1166.      * then reset the timer.  dur_timer() returns the duration in ms.
  1167.      */
  1168.     if (!run_timer(evp) || (dur_timer(evp)/1000L) > new_timer) {
  1169.         if (randomize == POLL_RANDOMCHANGE)
  1170.           new_timer =
  1171.             RANDOM_POLL(newpoll, ranp2(RANDOM_SPREAD(newpoll)))
  1172.               /* + current_time */;
  1173. #if 0
  1174.         TIMER_DEQUEUE(evp);
  1175.         evp->event_time = new_timer;
  1176.         TIMER_ENQUEUE(timerqueue, evp);
  1177. #else
  1178.         if (run_timer(evp))
  1179.           stop_timer (evp);
  1180.         evp->duration = SEC2TICKS(new_timer);
  1181.         start_timer (evp);
  1182. #endif /* 0 */
  1183.     }
  1184. }
  1185.  
  1186.  
  1187. /*
  1188.  * clear_all - clear all peer filter registers.  This is done after
  1189.  *           a step change in the time.
  1190.  */
  1191. void
  1192. clear_all()
  1193. {
  1194.     register int i;
  1195.     register struct peer *peer;
  1196.     extern void unpeer();
  1197.     void clear();
  1198.     void poll_update();
  1199.  
  1200.     for (i = 0; i < HASH_SIZE; i++)
  1201.         for (peer = peer_hash[i]; peer != 0; peer = peer->next) {
  1202.             /*
  1203.              * We used to drop all unconfigured pollers here.
  1204.              * The problem with doing this is that if your best
  1205.              * time source is unconfigured (there are reasons
  1206.              * for doing this) and you drop him, he may not
  1207.              * get around to polling you for a long time.  Hang
  1208.              * on to everyone, dropping their polling intervals
  1209.              * to the minimum.
  1210.              */
  1211.             clear(peer);
  1212.             poll_update(peer, NTP_MINPOLL, POLL_RANDOMCHANGE);
  1213.         }
  1214.  
  1215.     /*
  1216.      * Clear sys_peer.  We'll sync to one later.
  1217.      */
  1218.     sys_peer = 0;
  1219.  
  1220. }
  1221.  
  1222.  
  1223. /*
  1224.  * clear - clear peer filter registers.  See Section 3.4.7 of the spec.
  1225.  */
  1226. void
  1227. clear(peer)
  1228.     register struct peer *peer;
  1229. {
  1230.     extern char *ntoa();
  1231.  
  1232. #ifdef DEBUG
  1233.     if (debug)
  1234.         printf("clear(%s)\n", ntoa(&peer->srcadr));
  1235. #endif
  1236.     bzero(CLEAR_TO_ZERO(peer), LEN_CLEAR_TO_ZERO);
  1237.     peer->estdisp = PEER_MAXDISP;
  1238.  
  1239.     /*
  1240.      * Clear out the selection counters
  1241.      */
  1242.     peer->candidate = 0;
  1243.     peer->falseticker = 0;
  1244.     peer->select = peer->select_total = 0;
  1245.     peer->was_sane = 0;
  1246.  
  1247.     /*
  1248.      * Since we have a chance to correct possible funniness in
  1249.      * our selection of interfaces on a multihomed host, do so
  1250.      * by setting us to no particular interface.
  1251.      */
  1252.     peer->dstadr = any_interface;
  1253. }
  1254.  
  1255.  
  1256. /*
  1257.  * clock_filter - add incoming clock sample to filter register and run
  1258.  *          the filter procedure to find the best sample.
  1259.  */
  1260. void
  1261. clock_filter(peer, sample_offset, sample_delay, trustable)
  1262.     register struct peer *peer;
  1263.     l_fp *sample_offset;
  1264.     u_fp sample_delay;
  1265.     int trustable;
  1266. {
  1267.     register int i;
  1268.     register u_char *ord;
  1269.     register s_fp sample_soffset;
  1270.     extern char *ntoa();
  1271.     extern char *ufptoa();
  1272.     extern char *lfptoa();
  1273.  
  1274. #ifdef DEBUG
  1275.     if (debug)
  1276.         printf("clock_filter(%s, %s, %s)\n", ntoa(&peer->srcadr),
  1277.             lfptoa(sample_offset, 9), ufptoa(sample_delay, 4));
  1278. #endif
  1279.  
  1280.     /*
  1281.      * We keep a sort by delay of the current contents of the
  1282.      * shift registers.  We update this by (1) removing the
  1283.      * register we are going to be replacing from the sort, and
  1284.      * (2) reinserting it based on the new delay value.
  1285.      */
  1286.     ord = peer->filter_order;
  1287.     sample_soffset = LFPTOFP(sample_offset);
  1288.  
  1289.     for (i = 0; i < PEER_SHIFT-1; i++)    /* find old value */
  1290.         if (ord[i] == peer->filter_nextpt)
  1291.             break;
  1292.     for ( ; i < PEER_SHIFT-1; i++)    /* i is current, move everything up */
  1293.         ord[i] = ord[i+1];
  1294.     /* Here, last slot in ord[] is empty */
  1295.  
  1296.     if (sample_delay == 0)
  1297.         /*
  1298.          * Last slot for this guy.
  1299.          */
  1300.         i = PEER_SHIFT-1;
  1301.     else {
  1302.         register int j;
  1303.         register u_fp *delayp;
  1304.  
  1305.         delayp = peer->filter_delay;
  1306.         /*
  1307.          * Find where he goes in, then shift everyone else down
  1308.          */
  1309.         if (peer->hmode == MODE_BCLIENT) {
  1310.             register s_fp *soffsetp;
  1311.             /*
  1312.              * Sort by offset.  The most positive offset
  1313.              * should correspond to the minimum delay.
  1314.              */
  1315.             soffsetp = peer->filter_soffset;
  1316.             for (i = 0; i < PEER_SHIFT-1; i++)
  1317.                 if (delayp[ord[i]] == 0
  1318.                     || sample_soffset >= soffsetp[ord[i]])
  1319.                     break;
  1320.         } else {
  1321.             /*
  1322.              * Sort by delay.
  1323.              */
  1324.             for (i = 0; i < PEER_SHIFT-1; i++)
  1325.                 if (delayp[ord[i]] == 0
  1326.                     || sample_delay <= delayp[ord[i]])
  1327.                     break;
  1328.         }
  1329.  
  1330.         for (j = PEER_SHIFT-1; j > i; j--)
  1331.             ord[j] = ord[j-1];
  1332.     }
  1333.     ord[i] = peer->filter_nextpt;
  1334.  
  1335.     /*
  1336.      * Got everything in order.  Insert sample in current register
  1337.      * and increment nextpt.
  1338.      */
  1339.     peer->trust <<= 1;
  1340.     if (!trustable)
  1341.         peer->trust |= 1;
  1342.  
  1343.     peer->filter_delay[peer->filter_nextpt] = sample_delay;
  1344.     peer->filter_offset[peer->filter_nextpt] = *sample_offset;
  1345.     peer->filter_soffset[peer->filter_nextpt] = sample_soffset;
  1346.     peer->filter_nextpt++;
  1347.     if (peer->filter_nextpt >= PEER_SHIFT)
  1348.         peer->filter_nextpt = 0;
  1349.     
  1350.     /*
  1351.      * Now compute the dispersion, and assign values to estdelay and
  1352.      * estoffset.  If there are no samples in the register, estdelay and
  1353.      * estoffset go to zero and estdisp is set to the maximum.
  1354.      */
  1355.     if (peer->filter_delay[ord[0]] == 0) {
  1356.         peer->estdelay = 0;
  1357.         peer->estoffset.l_ui = peer->estoffset.l_uf = 0;
  1358.         peer->estsoffset = 0;
  1359.         peer->estdisp = PEER_MAXDISP;
  1360.     } else {
  1361.         register s_fp d;
  1362.  
  1363.         peer->estdelay = peer->filter_delay[ord[0]];
  1364.         peer->estoffset = peer->filter_offset[ord[0]];
  1365.         peer->estsoffset = LFPTOFP(&peer->estoffset);
  1366.         peer->estdisp = 0;
  1367.         for (i = 1; i < PEER_SHIFT; i++) {
  1368.             if (peer->filter_delay[ord[i]] == 0)
  1369.                 d = PEER_MAXDISP;
  1370.             else {
  1371.                 d = peer->filter_soffset[ord[i]]
  1372.                     - peer->filter_soffset[ord[0]];
  1373.                 if (d < 0)
  1374.                     d = -d;
  1375.                 if (d > PEER_MAXDISP)
  1376.                     d = PEER_MAXDISP;
  1377.             }
  1378.             /*
  1379.              * XXX This *knows* PEER_FILTER is 1/2
  1380.              */
  1381.             peer->estdisp += (u_fp)(d) >> i;
  1382.         }
  1383.         
  1384.         if (peer->hmode == MODE_BCLIENT) {
  1385.             register s_fp mdisp;
  1386.             /*
  1387.              * Note that BCLIENT delays aren't really
  1388.              * significant, since they really consist
  1389.              * of the precision of the peers involved
  1390.              * plus a constant value.  Yet the clock
  1391.              * selection procedure relies on them heavily
  1392.              * as a quality indicator.  What we do here
  1393.              * is compute the mean dispersion of the
  1394.              * samples in the registers and add twice
  1395.              * that to peer.estdelay.  This is an estimate
  1396.              * of the mean delay to the peer.  Doing this
  1397.              * will (1) make BCLIENT delays look worse than
  1398.              * polled delays, meaning the polled servers
  1399.              * will be preferred a little, and (2) makes
  1400.              * the noisiest servers look the worst.
  1401.              */
  1402.             mdisp = 0;
  1403.             for (i = 1; i < PEER_SHIFT; i++) {
  1404.                 if (peer->filter_delay[ord[i]] == 0)
  1405.                     mdisp += PEER_MAXDSPDEL;
  1406.                 else {
  1407.                     d = peer->filter_soffset[ord[0]]
  1408.                         - peer->filter_soffset[ord[i]];
  1409.                     if (d > PEER_MAXDSPDEL)
  1410.                         mdisp += PEER_MAXDSPDEL;
  1411.                     else
  1412.                         mdisp += d;
  1413.                 }
  1414.             }
  1415.             peer->estdelay += (mdisp << 1)/PEER_SHIFT;
  1416.         }
  1417.     }
  1418.     /*
  1419.      * We're done
  1420.      */
  1421. }
  1422.  
  1423.  
  1424.  
  1425. /*
  1426.  * clock_select - find the pick-of-the-litter clock
  1427.  */
  1428. void
  1429. clock_select(changed_peer)
  1430.     struct peer *changed_peer;    /* for a possible future optimization */
  1431. {
  1432.     register struct peer *peer;
  1433.     register int i;
  1434.     register int nlist;
  1435.     register s_fp d;
  1436.     register int j;
  1437.     register int n;
  1438.     u_fp local_threshold;
  1439.     struct peer *peer_list[NTP_MAXLIST];
  1440.     u_fp peer_badness[NTP_MAXLIST];
  1441.     struct peer *osys_peer;
  1442.  
  1443. #ifdef DEBUG
  1444.     if (debug)
  1445.         printf("clock_select()\n");
  1446. #endif
  1447.     /*
  1448.      * Calculate the fixed part of the dispersion limit
  1449.      */
  1450.     local_threshold = (FP_SECOND >> (-(int)sys_precision))
  1451.         + sys_maxskew;
  1452.  
  1453.     /*
  1454.      * This first chunk of code is supposed to go through all
  1455.      * peers we know about to find the NTP_MAXLIST peers which
  1456.      * are most likely to succeed.  We run through the list
  1457.      * doing the sanity checks and trying to insert anyone who
  1458.      * looks okay.  We are at all times aware that we should
  1459.      * only keep samples from the top two strata and we only need
  1460.      * NTP_MAXLIST of them.
  1461.      */
  1462.     nlist = 0;    /* none yet */
  1463.     for (n = 0; n < HASH_SIZE; n++) {
  1464.         for (peer = peer_hash[n]; peer != 0; peer = peer->next) {
  1465.             /*
  1466.              * Clear peer selection stats
  1467.              */
  1468.             peer->falseticker = 0;
  1469.             peer->candidate = 0;
  1470.             peer->select = 0;
  1471.             peer->select_total = 0;
  1472.             peer->was_sane = 0;
  1473.  
  1474.             if (peer->estdelay == 0)
  1475.                 continue;    /* not initialized */
  1476.             if (peer->stratum >= NTP_INFIN)
  1477.                 continue;    /* stratum no good */
  1478.             if (peer->stratum > 1
  1479.                 && peer->refid == peer->dstadr->sin.sin_addr.s_addr)
  1480.                 continue;    /* sync loop */
  1481.             if (peer->estdelay > NTP_MAXWGT) {
  1482.                 peer->seldelaytoolarge++;
  1483.                 continue;    /* too far away */
  1484.             }
  1485.             if (peer->estdisp > NTP_MAXWGT) {
  1486.                 peer->seldisptoolarge++;
  1487.                 continue;    /* too noisy or broken */
  1488.             }
  1489.             if (peer->org.l_ui < peer->reftime.l_ui) {
  1490.                 peer->selbroken++;
  1491.                 continue;    /* very broken host */
  1492.             }
  1493.             if (peer->trust != 0) {
  1494.                 continue;    /* not trustworthy */
  1495.             }
  1496.  
  1497.             /*
  1498.              * This one seems sane.  Find where he belongs
  1499.              * on the list.
  1500.              */
  1501.             peer->was_sane = 1;
  1502.             if (peer == sys_peer) {
  1503.                 d = 0;
  1504.             } else {
  1505.                 d = peer->estdisp + peer->dispersion
  1506.                     + local_threshold
  1507.                     + (FP_SECOND >> (-(int)peer->precision));
  1508.             }
  1509.             for (i = 0; i < nlist; i++)
  1510.                 if (peer->stratum <= peer_list[i]->stratum)
  1511.                     break;
  1512.             for ( ; i < nlist; i++) {
  1513.                 if (peer->stratum < peer_list[i]->stratum)
  1514.                     break;
  1515.                 if (d < peer_badness[i])
  1516.                     break;
  1517.             }
  1518.  
  1519.             /*
  1520.              * If i points past the end of the list, this
  1521.              * guy is a loser, else stick him in.
  1522.              */
  1523.             if (i >= NTP_MAXLIST)
  1524.                 continue;
  1525.             for (j = nlist; j > i; j--)
  1526.                 if (j < NTP_MAXLIST) {
  1527.                     peer_list[j] = peer_list[j-1];
  1528.                     peer_badness[j]
  1529.                         = peer_badness[j-1];
  1530.                 }
  1531.             
  1532.             peer_list[i] = peer;
  1533.             peer_badness[i] = d;
  1534.             if (nlist < NTP_MAXLIST)
  1535.                 nlist++;
  1536.         }
  1537.     }
  1538.  
  1539.     /*
  1540.      * Got the five-or-less best.  Cut the list where the number of
  1541.      * strata exceeds two.
  1542.      */
  1543.     j = 0;
  1544.     for (i = 1; i < nlist; i++)
  1545.         if (peer_list[i]->stratum > peer_list[i-1]->stratum)
  1546.             if (++j == 2) {
  1547.                 nlist = i;
  1548.                 break;
  1549.             }
  1550.  
  1551.     /*
  1552.      * Whew!  What we should have by now is 0 to 5 candidates for
  1553.      * the job of syncing us.  If we have none, we're out of luck.
  1554.      * If we have one, he's a winner.  If we have more, do falseticker
  1555.      * detection.  First record the position of each peer in the
  1556.      * the list for posterity.  Also determine if our system peer
  1557.      * made it.
  1558.      */
  1559.     for (i = 0; i < nlist; i++) {
  1560.         peer_list[i]->candidate = i+1;
  1561.         peer_list[i]->select_total = nlist;
  1562.     }
  1563.  
  1564.     osys_peer = sys_peer;
  1565.     if (nlist == 0)
  1566.         sys_peer = 0;
  1567.     else if (nlist == 1) {
  1568.         sys_peer = peer_list[0];
  1569.         sys_peer->falseticker = 1;
  1570.         sys_peer->select = 1;
  1571.     } else {
  1572.         /*
  1573.          * Re-sort by stratum, bdelay estimate quality and
  1574.          * peer.estdelay.
  1575.          */
  1576.         for (i = 0; i < nlist-1; i++)
  1577.             for (j = i+1; j < nlist; j++) {
  1578.                 if (peer_list[i]->stratum
  1579.                     < peer_list[j]->stratum)
  1580.                     break;    /* already sorted by stratum */
  1581.                 if (peer_list[i]->estdelay
  1582.                     < peer_list[j]->estdelay)
  1583.                     continue;
  1584.                 if (peer_list[i]->estdelay
  1585.                     > peer_list[j]->estdelay)
  1586.                     goto swapit;    /* sorry */
  1587.                 if (peer_list[i] == sys_peer)
  1588.                     continue;
  1589.                 if (peer_list[j] == sys_peer)
  1590.                     goto swapit;    /* and again */
  1591.                 if (ranp2(1) == 0)
  1592.                     continue;
  1593. swapit:
  1594.                 peer = peer_list[i];
  1595.                 peer_list[i] = peer_list[j];
  1596.                 peer_list[j] = peer;
  1597.             }
  1598.         
  1599.         /*
  1600.          * Record the ordering of peers before dropping any.
  1601.          */
  1602.         for (i = 0; i < nlist; i++)
  1603.             peer_list[i]->falseticker = i+1;
  1604.  
  1605.         /*
  1606.          * Now drop samples until we're down to one.
  1607.          */
  1608.         while (nlist > 1) {
  1609.             for (n = 0; n < nlist; n++) {
  1610.                 peer_badness[n] = 0;
  1611.                 peer = peer_list[n];
  1612.                 switch (sys_select_algorithm) {
  1613.                 case SELECT_1:
  1614.                     /*
  1615.                      * This code uses the 3/4 weight
  1616.                      * from the spec.
  1617.                      */
  1618.                     for (j = 0; j < nlist; j++) {
  1619.                         if (j == n)    /* with self? */
  1620.                         continue;
  1621.                     d = peer_list[j]->estsoffset
  1622.                         - peer->estsoffset;
  1623.                     if (d < 0)  /* absolute value */
  1624.                         d = -d;
  1625.                     /*
  1626.                      * XXX This code *knows* that
  1627.                      * NTP_SELECT is 3/4
  1628.                      */
  1629.                     for (i = 0; i < j; i++)
  1630.                         d = (d>>1) + (d>>2);
  1631.                                         
  1632.                                         peer_badness[n] += d;
  1633.                     }
  1634.                     break;
  1635.  
  1636.                 case SELECT_2:
  1637.                     /*
  1638.                      * This code reduces the wieghting
  1639.                      * of higher stratum peers with
  1640.                      * respect to lower by about 9%
  1641.                      */
  1642.                     for (j = 0; j < nlist; j++) {
  1643.                     if (j == n)    /* with self? */
  1644.                         continue;
  1645.                     d = peer_list[j]->estsoffset
  1646.                         - peer->estsoffset;
  1647.                     if (d < 0)  /* absolute value */
  1648.                         d = -d;
  1649.  
  1650.                     if (j > 0) {
  1651.                         /*
  1652.                          * Use the normal
  1653.                          * 3/4 weight but
  1654.                          * stop one short.
  1655.                          */
  1656.                         for (i = 0; i < (j-1); i++)
  1657.                         d = (d>>1) + (d>>2);
  1658.  
  1659.                         /*
  1660.                          * If the stratum of the
  1661.                          * jth peer is greater
  1662.                          * than the target, use
  1663.                          * a weight of 11/16
  1664.                          * instead of 3/4.
  1665.                          */
  1666.                         if (peer_list[j]->stratum
  1667.                           > peer->stratum)
  1668.                         d = (d>>1) + (d>>3) + (d>>4);
  1669.                         else
  1670.                         d = (d>>1) + (d>>2);
  1671.                     }
  1672.                 
  1673.                                         peer_badness[n] += d;
  1674.                     }
  1675.                     break;
  1676.  
  1677.                 case SELECT_3:
  1678.                     /*
  1679.                      * Like above, except weighting
  1680.                      * reduced by 18%.
  1681.                      */
  1682.                     for (j = 0; j < nlist; j++) {
  1683.                     if (j == n)    /* with self? */
  1684.                         continue;
  1685.                     d = peer_list[j]->estsoffset
  1686.                       - peer->estsoffset;
  1687.                     if (d < 0)  /* absolute value */
  1688.                         d = -d;
  1689.  
  1690.                     if (j > 0) {
  1691.                         /*
  1692.                          * Use the normal
  1693.                          * 3/4 weight but
  1694.                          * stop one short.
  1695.                          */
  1696.                         for (i = 0; i < (j-1); i++)
  1697.                         d = (d>>1) + (d>>2);
  1698.  
  1699.                         /*
  1700.                          * If the stratum of the
  1701.                          * jth peer is greater
  1702.                          * than the target, use
  1703.                          * a weight of 5/8
  1704.                          * instead of 3/4.
  1705.                          */
  1706.                         if (peer_list[j]->stratum
  1707.                           > peer->stratum)
  1708.                         d = (d>>1) + (d>>3);
  1709.                         else
  1710.                         d = (d>>1) + (d>>2);
  1711.                     }
  1712.                 
  1713.                                         peer_badness[n] += d;
  1714.                     }
  1715.                     break;
  1716.  
  1717.                 case SELECT_4:
  1718.                     /*
  1719.                      * This code uses the spec algorithm
  1720.                      * but with a weight of 11/16
  1721.                      */
  1722.                     for (j = 0; j < nlist; j++) {
  1723.                         if (j == n)    /* with self? */
  1724.                         continue;
  1725.                     d = peer_list[j]->estsoffset
  1726.                         - peer->estsoffset;
  1727.                     if (d < 0)  /* absolute value */
  1728.                         d = -d;
  1729.                     /*
  1730.                      * XXX This code *knows* that
  1731.                      * NTP_SELECT is 11/16
  1732.                      */
  1733.                     for (i = 0; i < j; i++)
  1734.                         d = (d>>1) + (d>>3) + (d>>4);
  1735.                 
  1736.                                         peer_badness[n] += d;
  1737.                     }
  1738.                     break;
  1739.  
  1740.                 case SELECT_5:
  1741.                     /*
  1742.                      * This code uses the spec algorithm
  1743.                      * but with a weight of 5/8
  1744.                      */
  1745.                     for (j = 0; j < nlist; j++) {
  1746.                         if (j == n)    /* with self? */
  1747.                         continue;
  1748.                     d = peer_list[j]->estsoffset
  1749.                         - peer->estsoffset;
  1750.                     if (d < 0)  /* absolute value */
  1751.                         d = -d;
  1752.                     /*
  1753.                      * XXX This code *knows* that
  1754.                      * NTP_SELECT is 5/8
  1755.                      */
  1756.                     for (i = 0; i < j; i++)
  1757.                         d = (d>>1) + (d>>3);
  1758.                 
  1759.                                         peer_badness[n] += d;
  1760.                     }
  1761.                     break;
  1762.  
  1763.                 default:
  1764.                     /*
  1765.                      * Hideous error.  Die for this.
  1766.                      */
  1767.                     syslog(LOG_ERR,
  1768.             "clock_select: select algorithm is %d!!!  Bye-bye.",
  1769.                     sys_select_algorithm);
  1770.                     /*exit(1);*/
  1771.                     /* NOS can't exit. */
  1772.                     return;
  1773.                 }
  1774.             }
  1775.  
  1776.             /*
  1777.              * We now have an array of nlist badness
  1778.              * coefficients.  Find the badest.  Find
  1779.              * the minimum precision while we're at
  1780.              * it.
  1781.              */
  1782.             i = 0;
  1783.             n = peer_list[0]->precision;;
  1784.             for (j = 1; j < nlist; j++) {
  1785.                 if (peer_badness[j] >= peer_badness[i])
  1786.                     i = j;
  1787.                 if (n > peer_list[j]->precision)
  1788.                     n = peer_list[j]->precision;
  1789.             }
  1790.             
  1791.             /*
  1792.              * i is the index of the peer with the worst
  1793.              * dispersion.  If his dispersion is less than
  1794.              * the threshold, stop now, else delete him and
  1795.              * continue around again.
  1796.              */
  1797.             if (peer_badness[i] < (local_threshold
  1798.                 + (FP_SECOND >> (-n))))
  1799.                 break;
  1800.             for (j = i + 1; j < nlist; j++)
  1801.                 peer_list[j-1] = peer_list[j];
  1802.             nlist--;
  1803.         }
  1804.  
  1805.         /*
  1806.          * What remains is a list of less than 5 peers.  First
  1807.          * record their order, then choose a peer.  If the
  1808.          * head of the list has a polling interval of NTP_MINPOLL
  1809.          * choose him right off.  If not, see if sys_peer is in
  1810.          * the list.  If so, keep him.  If not, take the top of
  1811.          * the list anyway.
  1812.          */
  1813.         for (i = 0; i < nlist; i++)
  1814.             peer_list[i]->select = i+1;
  1815.  
  1816.         if (peer_list[0]->ppoll <= NTP_MINPOLL
  1817.             || peer_list[0]->hpoll <= NTP_MINPOLL
  1818.             || sys_peer == 0
  1819.             || sys_peer->stratum > peer_list[0]->stratum) {
  1820.             sys_peer = peer_list[0];
  1821.         } else {
  1822.             for (i = 1; i < nlist; i++)
  1823.                 if (peer_list[i] == sys_peer)
  1824.                     break;
  1825.             if (i < nlist)
  1826.                 sys_wanderhold++;
  1827.             else
  1828.                 sys_peer = peer_list[0];
  1829.         }
  1830.     }
  1831.  
  1832.     /*
  1833.      * If we got a new system peer from all of this, clamp his polling
  1834.      * interval.  Also report the event.
  1835.      */
  1836.     if (osys_peer != sys_peer) {
  1837. #ifdef XNTP_MODE6
  1838.         report_event(EVNT_PEERSTCHG, (struct peer *)0);
  1839. #endif  /* XNTP_MODE6 */
  1840.         if (sys_peer != 0)
  1841.             poll_update(sys_peer, NTP_MINPOLL, POLL_NOTRANDOM);
  1842.     }
  1843. }
  1844.  
  1845.  
  1846.  
  1847.  
  1848. /*
  1849.  * fast_xmit - fast path send for stateless (non-)associations
  1850.  */
  1851. void
  1852. fast_xmit(rbufp, rmode, authentic)
  1853.     struct recvbuf *rbufp;
  1854.     int rmode;
  1855.     int authentic;
  1856. {
  1857.     struct pkt xpkt;
  1858.     register struct pkt *rpkt;
  1859.     u_char xmode;
  1860.     u_short xkey;
  1861.     int docrypt;
  1862.     l_fp xmt_ts;
  1863.     extern void unpeer();
  1864. #ifdef XNTP_AUTHENTICATE
  1865.     extern void auth1crypt();
  1866.     extern void auth2crypt();
  1867. #endif /* XNTP_AUTHENTICATE */
  1868.     extern void sendpkt();
  1869.     extern void get_systime();
  1870.     extern char *ntoa();
  1871.  
  1872. #ifdef DEBUG
  1873.     if (debug)
  1874.         printf("fast_xmit(%s, %d)\n", ntoa(&rbufp->recv_srcadr), rmode);
  1875. #endif
  1876.  
  1877.     /*
  1878.      * Make up new packet and send it quick
  1879.      */
  1880.     rpkt = &rbufp->recv_pkt;
  1881.     if (rmode == MODE_ACTIVE)
  1882.         xmode = MODE_PASSIVE;
  1883.     else
  1884.         xmode = MODE_SERVER;
  1885.  
  1886. #ifdef XNTP_AUTHENTICATE
  1887.     if (rbufp->recv_length == LEN_PKT_MAC) {
  1888.         docrypt = 1;
  1889.         if (authentic)
  1890.             xkey = ntohl(rpkt->keyid);
  1891.         else
  1892.             xkey = 0;
  1893.     } else
  1894. #endif /* XNTP_AUTHENTICATE */
  1895.     {
  1896.         docrypt = 0;
  1897.     }
  1898.  
  1899.     xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
  1900.         PKT_VERSION(rpkt->li_vn_mode), xmode);
  1901.     xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
  1902.     xpkt.ppoll = max(NTP_MINPOLL, rpkt->ppoll);
  1903.     xpkt.precision = sys_precision;
  1904.     xpkt.distance = HTONS_FP(sys_distance);
  1905.     xpkt.dispersion = HTONS_FP(sys_dispersion);
  1906.     xpkt.refid = sys_refid;
  1907.     HTONL_FP(&sys_reftime, &xpkt.reftime);
  1908.     xpkt.org = rpkt->xmt;
  1909.     HTONL_FP(&rbufp->recv_time, &xpkt.rec);
  1910.  
  1911.     /*
  1912.      * If we are encrypting, do it.  Else don't.  Easy.
  1913.      */
  1914. #ifdef XNTP_AUTHENTICATE
  1915.     if (docrypt) {
  1916.         xpkt.keyid = htonl(xkey);
  1917.         auth1crypt(xkey, (u_long *)&xpkt, LEN_PKT_NOMAC);
  1918.         get_systime(&xmt_ts);
  1919.         L_ADDUF(&xmt_ts, sys_authdelay);
  1920.         HTONL_FP(&xmt_ts, &xpkt.xmt);
  1921.         auth2crypt(xkey, (u_long *)&xpkt, LEN_PKT_NOMAC);
  1922.         sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, &xpkt, LEN_PKT_MAC);
  1923.     } else
  1924. #endif /* XNTP_AUTHENTICATE */
  1925.     {
  1926.         /*
  1927.          * Get xmt timestamp, then send it without mac field
  1928.          */
  1929.         get_systime(&xmt_ts);
  1930.         HTONL_FP(&xmt_ts, &xpkt.xmt);
  1931.         sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, &xpkt,
  1932.             LEN_PKT_NOMAC);
  1933.     }
  1934. }
  1935.  
  1936.  
  1937.  
  1938. /*
  1939.  * init_proto - initialize the protocol module's data
  1940.  */
  1941. void
  1942. init_proto()
  1943. {
  1944.     /*
  1945.      * Fill in the sys_* stuff.  Default is don't listen
  1946.      * to broadcasting, don't authenticate.
  1947.      */
  1948.     sys_leap = LEAP_NOTINSYNC;
  1949.     sys_stratum = STRATUM_UNSPEC;
  1950.     sys_precision = (s_char)DEFAULT_SYS_PRECISION;
  1951.     sys_distance = 0;
  1952.     sys_dispersion = 0;
  1953.     sys_refid = 0;
  1954.     sys_reftime.l_ui = sys_reftime.l_uf = 0;
  1955.     sys_hold = (PEER_SHIFT * (1<<NTP_MINPOLL));    /* wait before pick */
  1956.     sys_peer = 0;
  1957.     sys_maxskew = NTP_MAXSKW;
  1958.  
  1959.     sys_bclient = 0;
  1960.     sys_bdelay = DEFBROADDELAY;
  1961.  
  1962.     sys_authenticate = 0;
  1963.     sys_select_algorithm = SELECT_1;
  1964.  
  1965.     sys_stattime = 0;
  1966.     sys_badstratum = 0;
  1967.     sys_oldversionpkt = 0;
  1968.     sys_badlength = 0;
  1969.     sys_newversionpkt = 0;
  1970.     sys_unknownversion = 0;
  1971.     sys_processed = 0;
  1972.     sys_badauth = 0;
  1973.     sys_wanderhold = 0;
  1974. }
  1975.  
  1976.  
  1977.  
  1978. /*
  1979.  * proto_config - configure the protocol module
  1980.  */
  1981. void
  1982. proto_config(item, value)
  1983.     int item;
  1984.     long value;
  1985. {
  1986.     /*
  1987.      * Figure out what he wants to change, then do it
  1988.      */
  1989.     switch (item) {
  1990.     case PROTO_BROADCLIENT:
  1991.         /*
  1992.          * Turn on/off facility to listen to broadcasts
  1993.          */
  1994.         sys_bclient = (int)value;
  1995.         if (sys_bclient)
  1996.             io_setbclient();
  1997.         else
  1998.             io_unsetbclient();
  1999.         break;
  2000.     
  2001.     case PROTO_PRECISION:
  2002.         /*
  2003.          * Set system precision
  2004.          */
  2005.         sys_precision = (s_char)value;
  2006.         break;
  2007.     
  2008.     case PROTO_BROADDELAY:
  2009.         /*
  2010.          * Set default broadcast delay
  2011.          */
  2012.         sys_bdelay = (u_fp)value;
  2013.         break;
  2014.     
  2015. #ifdef XNTP_AUTHENTICATE
  2016.     case PROTO_AUTHENTICATE:
  2017.         /*
  2018.          * Specify the use of authenticated data
  2019.          */
  2020.         sys_authenticate = (int)value;
  2021.         break;
  2022.  
  2023.     case PROTO_AUTHDELAY:
  2024.         /*
  2025.          * Provide an authentication delay value.  Round it to
  2026.          * the microsecond.  This is crude.
  2027.          */
  2028.         sys_authdelay = (((u_long)value) + 0x00000800) & 0xfffff000;
  2029.         break;
  2030. #endif  /* XNTP_AUTHENTICATE */
  2031.  
  2032.     case PROTO_MAXSKEW:
  2033.         /*
  2034.          * Set the maximum skew value
  2035.          */
  2036.         sys_maxskew = (u_fp)value;
  2037.         break;
  2038.  
  2039.     case PROTO_SELECT:
  2040.         /*
  2041.          * Set the selection algorithm.  Check this value, since
  2042.          * invalid values will break things.
  2043.          */
  2044.         if (value < SELECT_1 || value > SELECT_5) {
  2045.             syslog(LOG_ERR,
  2046.                 "proto_config: illegal selection algorithm %ld",
  2047.                 value);
  2048.         } else {
  2049.             sys_select_algorithm = (int)value;
  2050.         }
  2051.         break;
  2052.  
  2053.     default:
  2054.         /*
  2055.          * Log this error
  2056.          */
  2057.         syslog(LOG_ERR, "proto_config: illegal item %d, value %ld",
  2058.             item, value);
  2059.         break;
  2060.     }
  2061. }
  2062.  
  2063.  
  2064. /*
  2065.  * proto_clr_stats - clear protocol stat counters
  2066.  */
  2067. void
  2068. proto_clr_stats()
  2069. {
  2070.     sys_badstratum = 0;
  2071.     sys_oldversionpkt = 0;
  2072.     sys_newversionpkt = 0;
  2073.     sys_unknownversion = 0;
  2074.     sys_badlength = 0;
  2075.     sys_processed = 0;
  2076.     sys_badauth = 0;
  2077.     sys_wanderhold = 0;
  2078.     sys_stattime = current_time;
  2079. }
  2080.